#ifndef __MVVCD_H__
#define __MVVCD_H__

/**
 * @brief 兼容旧版本定义头文件，全新版本开发可直接使用mvdef.h
 */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#include "mvdef.h"

/*************************************
              old type
*************************************/
#define mvvcd_void_t    mv_void_t
#define mvvcd_v8_t      mv_v8_t
#define mvvcd_f32_t     mv_f32_t
#define mvvcd_f64_t     mv_f64_t
#define mvvcd_f32_t     mv_f32_t
#define mvvcd_f64_t     mv_f64_t
#define mvvcd_float32_t mv_f32_t
#define mvvcd_float64_t mv_f64_t
#define mvvcd_u8_t      mv_u8_t
#define mvvcd_u16_t     mv_u16_t
#define mvvcd_u32_t     mv_u32_t
#define mvvcd_u64_t     mv_u64_t
#define mvvcd_s8_t      mv_s8_t
#define mvvcd_s16_t     mv_s16_t
#define mvvcd_s32_t     mv_s32_t
#define mvvcd_s64_t     mv_s64_t
#define mvvcd_cv8_t     mv_cv8_t
#define mvvcd_cf32_t    mv_cf32_t
#define mvvcd_cf64_t    mv_cf64_t
#define mvvcd_cu8_t     mv_cu8_t
#define mvvcd_cu16_t    mv_cu16_t
#define mvvcd_cu32_t    mv_cu32_t
#define mvvcd_cu64_t    mv_cu64_t
#define mvvcd_cs8_t     mv_cs8_t
#define mvvcd_cs16_t    mv_cs16_t
#define mvvcd_cs32_t    mv_cs32_t
#define mvvcd_cs64_t    mv_cs64_t
#define mvvcd_vptr_t    mv_vptr_t
#define mvvcd_v8ptr_t   mv_v8ptr_t
#define mvvcd_f32ptr_t  mv_f32ptr_t
#define mvvcd_f64ptr_t  mv_f64ptr_t
#define mvvcd_u8ptr_t   mv_u8ptr_t
#define mvvcd_u16ptr_t  mv_u16ptr_t
#define mvvcd_u32ptr_t  mv_u32ptr_t
#define mvvcd_u64ptr_t  mv_u64ptr_t
#define mvvcd_s8ptr_t   mv_s8ptr_t
#define mvvcd_s16ptr_t  mv_s16ptr_t
#define mvvcd_s32ptr_t  mv_s32ptr_t
#define mvvcd_s64ptr_t  mv_s64ptr_t
#define mvvcd_cvptr_t   mv_cvptr_t
#define mvvcd_cv8ptr_t  mv_cv8ptr_t
#define mvvcd_cf32ptr_t mv_cf32ptr_t
#define mvvcd_cf64ptr_t mv_cf64ptr_t
#define mvvcd_cu8ptr_t  mv_cu8ptr_t
#define mvvcd_cu16ptr_t mv_cu16ptr_t
#define mvvcd_cu32ptr_t mv_cu32ptr_t
#define mvvcd_cu64ptr_t mv_cu64ptr_t
#define mvvcd_cs8ptr_t  mv_cs8ptr_t
#define mvvcd_cs16ptr_t mv_cs16ptr_t
#define mvvcd_cs32ptr_t mv_cs32ptr_t
#define mvvcd_cs64ptr_t mv_cs64ptr_t
/*************************************
          argument direction
*************************************/
#define MVVCD_ARG_IN      //fill in
#define MVVCD_ARG_IN_OPT  //fill in (optional)
#define MVVCD_ARG_OUT     //take out
#define MVVCD_ARG_OUT_OPT //take out(optional)
#define MVVCD_ARG_DUAL    //fill in & take out


#define MVVCD_EC_SUCCESS          MV_EC_SUCCESS         
#define MVVCD_EC_FAILED           MV_EC_FAILED          
#define MVVCD_EC_ABORT            MV_EC_ABORT           
#define MVVCD_EC_RETRY            MV_EC_RETRY           
#define MVVCD_EC_IGNORE           MV_EC_IGNORE          
#define MVVCD_EC_NOT_INIT         MV_EC_NOT_INIT        ///<mostly shows that the function/module was not inited
#define MVVCD_EC_INVALID_ARGS     MV_EC_INVALID_ARGS    ///<some of input arguments is illegal or invalid
#define MVVCD_EC_REDEF            MV_EC_REDEF           ///<some init/defined is init/define again
#define MVVCD_EC_MALLOC_FAILED    MV_EC_MALLOC_FAILED   ///<malloc/alloc/realloc failed
#define MVVCD_EC_RESOURCE_LEAK    MV_EC_RESOURCE_LEAK   ///<some predistribution resource is not enough for this request action
#define MVVCD_EC_NOT_FOUND        MV_EC_NOT_FOUND       ///<target not found in request action
#define MVVCD_EC_TIMEOUT          MV_EC_TIMEOUT         ///<timeout
#define MVVCD_EC_CONNECT_ERROR    MV_EC_CONNECT_ERROR   ///<mostly is connect to target server failed
#define MVVCD_EC_RSP_ERROR        MV_EC_RSP_ERROR       ///<mostly is the server response not expected
#define MVVCD_EC_VERIFY_FAILED    MV_EC_VERIFY_FAILED   ///<failed of any verify method
#define MVVCD_EC_ACTION_BUSY      MV_EC_ACTION_BUSY     ///<mostly is busy calling by multi-caller or in some unchangeable status that call comes failed
#define MVVCD_EC_OUT_OF_RANGE     MV_EC_OUT_OF_RANGE    ///<mostly is a num out of the specified range
#define MVVCD_EC_NOT_MATCH        MV_EC_NOT_MATCH       ///<mostly is comparison failed
#define MVVCD_EC_GET_HOST_FAILED  MV_EC_GET_HOST_FAILED ///<host ip analyze failed
#define MVVCD_EC_SOCKET_ERROR     MV_EC_SOCKET_ERROR    ///<socket create failed
#define MVVCD_EC_NOT_READY        MV_EC_NOT_READY       ///<mostly is a status check result shown that some action is not ready yet
#define MVVCD_EC_IO_ERROR         MV_EC_IO_ERROR        ///<mostly is file input/output ctrl error
#define MVVCD_EC_NOT_SUPPORT      MV_EC_NOT_SUPPORT     ///<mostly is function/api is not available when compiling or hardware adaption

/**************************************
 *        memory copy
 *************************************/
#define MVVCD_MEM_FILL(dst, src, len, offset) {memcpy(dst+offset, src, len); offset+=len;}

#define MVVCD_MEM_POP(dst, src, len, offset)  {memcpy(dst, src+offset, len); offset+=len;}

/**************************************
 *        pthread tools
 *************************************/
/**
 * @Brief: malloc a heap arglist memory to save args for pthread using, free by user(pthread)
 * @Param:
 *    [OUT] p_tgt: takeout target memory address pointer
 *     [in] P_SRC: source arglist memory address
 *     [IN] T: arglist type
 *     [IN] ERR_ACT: action when error occur (malloc failed)
 */
#define MVVCD_THREAD_HEAP_ARGLIST(p_tgt, p_src, T, ERR_ACT) {p_tgt = malloc(sizeof(T)); if (NULL == p_tgt) {ERR_ACT}; memcpy(p_tgt, p_src, sizeof(T));}
/**
 * @Brief: to create a thread to handle remote request
 * @Param:
 *     [IN] enrty: pthread func entry
 *     [IN] stack_size: pthread specify stack size
 *     [IN] args: pthread push in args
 *     [IN] arg_copy: need copy @args in heap locally (0=no, 1=yes)
 *     [IN] T: type of @args
 *     [IN] result: takeout create result
 * @Return:(result)
 *     MVVCD_EC_MALLOC_FAILED (memory malloc or thread create failed)
 * @Note:
 *     default use -DHIGH_POLICY_THREAD
 */
#define MVVCD_THREAD_CREATE(tid, entry, stack_size, high_sch, args, arg_copy, T, result) \
{\
	T *p_args = NULL;\
	pthread_attr_t _attr;\
	memset(&_attr, 0, sizeof(pthread_attr_t));\
	pthread_attr_init(&_attr);\
	pthread_attr_setscope (&_attr,       PTHREAD_SCOPE_SYSTEM);\
	pthread_attr_setdetachstate (&_attr, PTHREAD_CREATE_DETACHED);\
	pthread_attr_setstacksize(&_attr,    stack_size);\
\
	if (high_sch) {\
		pthread_attr_setinheritsched(&_attr, PTHREAD_EXPLICIT_SCHED);\
		pthread_attr_setschedpolicy(&_attr, SCHED_RR);\
		struct sched_param schp;\
		schp.sched_priority = 90; \
		pthread_attr_setschedparam(&_attr, &schp);\
	}\
\
	do {\
		if (arg_copy) {\
			MVVCD_THREAD_HEAP_ARGLIST(p_args, args, T, {result = MVVCD_EC_MALLOC_FAILED;break;});\
		} else {\
			p_args = args;\
		}\
		result = pthread_create(&tid, &_attr, (mvvcd_vptr_t)entry, (mvvcd_vptr_t)p_args);\
		pthread_attr_destroy(&_attr);\
		if (0 != result) {\
			printf("[l:%d]pthread create failed (errno:%d)", __LINE__, errno);\
			if ((0 != arg_copy) && (NULL != p_args)) {\
				free(p_args);\
			}\
			result = MVVCD_EC_MALLOC_FAILED;\
		}\
	}while(0);\
}

#endif
